#ifndef unigame_Vector2_h
#define unigame_Vector2_h

#include <math.h>
#include "math/Math.h"

namespace unigame
{
	template <class T>
	class Vector2
	{
	public:
		Vector2():x(0), y(0){}
		Vector2(T x1, T y1):x(x1), y(y1){}
		~Vector2(){}

		Vector2(const Vector2<T>& v):x(v.x), y(v.y){}

		void set(T x, T y)
		{
			this->x = x;
			this->y = y;
		}

		T dot(const Vector2<T>& v) const
		{
			return x * v.x + y * v.y;
		}

		Vector2<T> operator -()
		{
			return Vector2<T>(-x, -y);
		}

		Vector2<T>& operator =(const Vector2<T> v)
		{
			x = v.x;
			y = v.y;
			return *this;
		}

		bool operator ==(const Vector2<T>& v)
		{
			return x == v.x && y == v.y;
		}

		bool operator !=(const Vector2<T>& v)
		{
			return x != v.x || y != v.y;
		}

		Vector2<T> operator +(const Vector2<T>& v) const
		{
			return Vector2<T>(x + v.x, y + v.y);
		}

		Vector2<T> operator -(const Vector2<T>& v) const
		{
			return Vector2<T>(x - v.x, y - v.y);
		}

		Vector2<T> operator *(const T value) const
		{
			return Vector2<T>(x * value, y * value);
		}

		Vector2<T> operator /(const T value) const
		{
			return Vector2<T>(x / value, y / value);
		}

		Vector2<T>& operator +=(const Vector2<T>& v)
		{
			x += v.x;
			y += v.y;
			return *this;
		}

		Vector2<T>& operator -=(const Vector2<T>& v)
		{
			x -= v.x;
			y -= v.y;
			return *this;
		}

		Vector2<T>& operator *=(const T value)
		{
			x *= value;
			y *= value;
			return *this;
		}

		Vector2<T>& operator /=(const T value)
		{
			x /= value;
			y /= value;
			return *this;
		}

		T& operator [](const int32u index)
		{
			return getValuePtr()[index];
		}

		T squrMag()
		{
			return x * x + y * y;
		}

		float mag()
		{
			return 1 / Math::invSqrt(squrMag());
		}

		void normalize()
		{
			float m = Math::invSqrt(squrMag());
			x *= m;
			y *= m;
		}

	private:
		T* getValuePtr()
		{
			return reinterpret_cast<T*>(this);
		}
	
	public:
		T x;
		T y;
	};

	typedef Vector2<float> Vector2f;
}

#endif